package com.inderlab.jpin;

import java.io.*;
import java.util.Hashtable;
import java.util.TreeMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Map;
import java.util.Enumeration;

public class JPCodeBook
{
	
	public  static TreeMap<String,Integer>  tm  = new TreeMap<String,Integer>();
	public  static TreeMap<Integer,Integer> tmi = new TreeMap<Integer,Integer>();
	
	private static String codebook_file = "codebook.txt";
	private static int umcode = 1;
	private static boolean filemode = false;
	private static boolean compactmode = com.inderlab.jpin.JPAgent.compactmode;
	private static boolean verbosemode = com.inderlab.jpin.JPAgent.verbosemode;
	private static boolean sidemode = com.inderlab.jpin.JPAgent.sidemode;

	public static int callcounter = 1;
	
	private static BufferedWriter outfp = null;
		private static boolean codebook_saved = true;
		
	// Register to codebook
	public static void register(String classname, String methodname)
	{	
		String codekey = classname.replace("/",".")+"."+methodname;
		if(!tm.containsKey(codekey)) 
		{
			addCode(codekey, umcode++);			
		}
	}
	
	
	// Add to TreeMap
	private synchronized static void addCode(String codekey, int value)
	{
		//if(compactmode)
		//	System.out.println("SAVE Key="+codekey.replace("/",".")+" value="+value);
		// System.out.println("KEY:"+value+" "+codekey+" "+tm.size()+" / "+(umcode-1));

		tm.put(codekey, new Integer(value));
		tmi.put(new Integer(value), new Integer(0));		
		
		// Debug
		// writeCode(codekey, value);
	}
	
	// Get the code with classname and methodname
	public static int getCode(String codekey)
	{
		//if(compactmode)
		//	System.out.println("GET Key="+codekey+" value="+tm.get(codekey));
		
		if(tm.get(codekey)==null) 
			return -1;
		else
			return tm.get(codekey).intValue();
	}

	// Debug Use
	private static void writeCode(String codekey, int value)
	{
		try {		 
			if(outfp==null) {
				outfp = new BufferedWriter(new FileWriter(codebook_file, false));								
			}			
			outfp.write(value+" "+codekey+"\n");
		} catch(IOException ex) 
		{
				System.out.println((sidemode ? JPColor.MARGIN:"")+JPColor.C5+ex+"[CodeBook] writeCode - File Error :"+ex+JPColor.RESET);						
		}
	}
	
	// Save all codebook entries
	// Invoke by Shutdown Hook from Agent
	public synchronized static void writeCodeBook()
	{
		try {		 
			if(outfp==null) {
				outfp = new BufferedWriter(new FileWriter(codebook_file, false));				
			}
			
			outfp.write("[SIZE] "+tm.size()+"\n");
			
			Iterator i = tm.entrySet().iterator();
			while(i.hasNext())
			{
				Map.Entry me = (Map.Entry) i.next();
				outfp.write(me.getValue()+" "+me.getKey()+"\n");
	     	}
 			outfp.write("[END]\n");		

			outfp.flush();
		    outfp.close();
		} catch(IOException ex) 
		{
			System.out.println((sidemode ? JPColor.MARGIN:"")+JPColor.C5+"[CodeBook] writeCodeBook - File Error :"+ex+JPColor.RESET);						
		}
	}
	
}